﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Data;
using System.Configuration;
using System.Web;
using System.Xml;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Rookey.Frame.IMCore;
using Rookey.Frame.IMCore.IO;
using Rookey.Frame.IMCore.Text;
using System.Threading;

/// <summary>
///DownloadHandler 的摘要说明
/// </summary>
namespace Rookey.Frame.IMWeb
{
	public class DownloadMsg : IHttpHandler, IComparer<Message>
	{
		static object m_TempLock = new object();
		static DateTime m_TempFileLWT;
		static TextTemplate m_Template = null;

		static String MessageHtmlFormat =
		@"<div class='message' style='background-color:{3}'>" +
			@"<div class='messageTitle'>" +
				@"<span class='sender'>{0}</span><span class='time'>{1:yyyy-MM-dd HH:mm:ss}</span>" +
			@"</div>" +
			@"<div class='messageContent'>{2}</div>" +
		@"</div>" +
		@"<br/>";

		static String FileHtmlFormat =
		"<div class='div_filename'>文件名:{0}</div>" +
			"<div class='operationContainer'>" +
			"<div class='link_download'><a target='_blank' href='{2}?FileName={1}'>下载</a></div>" +
		"</div>";

		static Regex Regex_Download = new Regex(@"(<[^<>]+)src=(\x22|\x27)([^\f\n\r\t\v<>\x22\x27]+/|)download.aspx\x3FFileName=([^\f\n\r\t\v<>\x22\x27]+)(\x22|\x27)([^<>]*>)", RegexOptions.IgnoreCase);
		static Regex Regex_File = new Regex(@"\x5BFILE\x3A([^\f\n\r\t\v\x5B\x5D]+)\x5D", RegexOptions.IgnoreCase);
		static Regex Regex_A = new Regex(@"(\x5B\/A\x5D|\x5BA\x3A([^\f\n\r\t\v\x5B\x5D]+)\x5D)", RegexOptions.IgnoreCase);

		static DownloadMsg()
		{
		}

		HttpContext _context;
		String _path;

		public DownloadMsg()
		{
		}

		string ReplaceDownload(Match m)
		{
			return String.Format(
				"{2}src=\"{0}?FileName={1}\"{3}",
				_path,
				m.Groups[4].Value.StartsWith("/") ? m.Groups[4].Value : String.Format("/{0}/{1}", ServerImpl.Instance.GetUserName(_context), m.Groups[4].Value),
				m.Groups[1].Value,
				m.Groups[6].Value
			);
		}

		string ReplaceFile(Match m)
		{
			return string.Format(
				FileHtmlFormat,
				Microsoft.JScript.GlobalObject.unescape(Path.GetFileName(m.Groups[1].Value)),
				m.Groups[1].Value.StartsWith("/") ? m.Groups[1].Value : String.Format("/{0}/{1}", ServerImpl.Instance.GetUserName(_context), m.Groups[1].Value),
				_path
			);
		}

		string ReplaceA(Match m)
		{
			if (m.Value == "[/A]") return "</a>";
			else return string.Format("<a target='_black' href='{0}'>", Microsoft.JScript.GlobalObject.unescape(m.Groups[2].Value));
		}

		void IHttpHandler.ProcessRequest(HttpContext context)
		{
			lock (m_TempLock)
			{
				FileInfo fi = new FileInfo("/administrator/Public/Data/history.htm");
				if (m_Template == null || m_TempFileLWT < fi.LastWriteTime)
				{
					using (System.IO.Stream stream = Rookey.Frame.IMCore.IO.File.Open("/administrator/Public/Data/history.htm", System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Read, System.IO.FileShare.None))
					{
						Byte[] buffer = new Byte[stream.Length];
						stream.Read(buffer, 0, buffer.Length);
						string content = System.Text.Encoding.UTF8.GetString(buffer);
						m_Template = new TextTemplate(content);
					}
					m_TempFileLWT = fi.LastWriteTime;
				}
			}

			_context = context;

			_path = string.Format(
				"http://{0}{1}{2}/download.aspx",
				_context.Request.Url.Host,
				_context.Request.Url.Port == 80 ? "" : ":" + _context.Request.Url.Port.ToString(),
				ServerImpl.Instance.ServiceUrl
			);

			AccountInfo cu = Rookey.Frame.IMCore.AccountImpl.Instance.GetUserInfo(ServerImpl.Instance.GetUserName(context));
			AccountInfo peer = Rookey.Frame.IMCore.AccountImpl.Instance.GetUserInfo(Convert.ToInt32(context.Request.QueryString["Peer"]));

			context.Response.ContentType = "application/octet-stream";
			context.Response.AppendHeader("Content-Disposition", "attachment;filename=history.htm");

            List<Message> messages = MessageImpl.Instance.FindHistory(cu.Name, peer.Name, new DateTime(2000, 1, 1), new DateTime(2100, 1, 1));
			messages.Sort(this);

			StringBuilder msg_content = new StringBuilder();
			int count = 0;
			foreach (Message msg in messages)
			{
				string content = Regex_Download.Replace(msg.Content, ReplaceDownload);
				content = Regex_File.Replace(content, ReplaceFile);
				content = Regex_A.Replace(content, ReplaceA);
				msg_content.AppendFormat(MessageHtmlFormat,
					msg.Sender.Nickname, msg.CreatedTime, content,
					count % 2 != 0 ? "#FFFFFF" : "#F8FCFF"
				);
				count++;
			}

			Hashtable values = new Hashtable();
			values["SENDER"] = cu.Nickname;
			values["RECEIVER"] = peer.Nickname;
			values["MESSAGES"] = msg_content.ToString();

			context.Response.Write(m_Template.Render(values));
		}

		bool IHttpHandler.IsReusable
		{
			get { return true; }
		}

		int IComparer<Message>.Compare(Message m1, Message m2)
		{
			if (m1.CreatedTime > m2.CreatedTime) return 1;
			if (m1.CreatedTime < m2.CreatedTime) return -1;
			return 0;
		}
	}
}